
// Copyright (C) Recursion Company. All rights reserved.

#ifndef __WTL_UI_COLOR_PICKER_H__
#define __WTL_UI_COLOR_PICKER_H__

#define MWM_SELCHANGE     (_MW_MSG_FIRST + 200)
#define MWM_SELENDOK      (_MW_MSG_FIRST + 201)
#define MWM_SELENDCANCEL  (_MW_MSG_FIRST + 202)
#define MWM_CLOSEUP       (_MW_MSG_FIRST + 203)
#define MWM_DROPDOWN      (_MW_MSG_FIRST + 204)

typedef struct
{
    const TCHAR* szName;
    COLORREF crColour;
}
ColourTableEntry;

class CColourPopup : public CWindowImpl<CColourPopup>
{
public:
    DECLARE_WND_CLASS_EX (_T ("VolColourPopup"), (CS_CLASSDC | CS_SAVEBITS | CS_HREDRAW | CS_VREDRAW), COLOR_BTNFACE)

    inline_ CColourPopup ()
    {
        init ();
    }

    CColourPopup (INT x, INT y, COLORREF crInitialColour, HWND hParentWnd, const TCHAR* szDefaultColorName,
            COLORREF clrDefault, const TCHAR* szCustomColorName);
    ~CColourPopup ();

public:
    BOOL Create (INT x, INT y, COLORREF crInitialColour, HWND hParentWnd, const TCHAR* szDefaultColorName,
            COLORREF clrDefault, const TCHAR* szCustomColorName);

    virtual void OnFinalMessage (HWND hWnd) override;

    BEGIN_MSG_MAP_EX (CColourPopup)
        ProcessToolTip (uMsg, wParam, lParam);
        MSG_WM_LBUTTONUP (OnLButtonUp)
        MSG_WM_LBUTTONDOWN (OnLButtonDown)
        MSG_WM_PAINT (OnPaint)
        MSG_WM_MOUSEMOVE (OnMouseMove)
        MSG_WM_KEYDOWN (OnKeyDown)
        MSG_WM_QUERYNEWPALETTE (OnQueryNewPalette)
        MSG_WM_PALETTECHANGED (OnPaletteChanged)
        MSG_WM_KILLFOCUS (OnKillFocus)
        MSG_WM_ACTIVATEAPP (OnActivateApp)
        MSG_WM_SETCURSOR (OnSetCursor)
    END_MSG_MAP_EX ()

protected:
    void init ();
    BOOL GetCellRect (INT nIndex, CRect& rect);
    void FindCellFromColour (COLORREF crColour);
    void UpdateWindowPos (INT xLeft, INT yTop);
    void CreateToolTips ();
    void ChangeSelection (INT nIndex);
    void EndSelection (INT nMessage);
    void DrawCell (CDC* pDC, INT nIndex);
    void ProcessToolTip (UINT uMsg, WPARAM wParam, LPARAM lParam);

    inline_ COLORREF GetColour (INT nIndex)  { return m_crColours[nIndex].crColour; }
    inline_ const TCHAR* GetColourName(INT nIndex)  { return m_crColours[nIndex].szName; }
    INT GetIndex (INT row, INT col) const;
    INT GetRow (INT nIndex) const;
    INT GetColumn (INT nIndex) const;

public:
    #define _NUM_COLOUR_TABLE_ENTRIES  32
    static ColourTableEntry m_crColours [];
    static const TCHAR* sGetColorName (COLORREF clr);

protected:
    INT          m_nNumColours;
    INT          m_nNumColumns, m_nNumRows;
    INT          m_nBoxSize, m_nMargin;
    INT          m_nCurrentSel;
    INT          m_nChosenColourSel;
    CString      m_strDefaultColorName;
    COLORREF     m_crDefault;
    CString      m_strCustomColorName;
    CRect        m_rtCustomText, m_rtDefaultText, m_rtWindow;
    CFont        m_objFont;
    CPalette     m_objPalette;
    COLORREF     m_crInitialColour, m_crColour;
    CToolTipCtrl m_objToolTip;
    HWND         m_hParentWnd;
    BOOL         m_blHited;
    BOOL         m_blDlgEntried;

protected:
    void OnLButtonUp (UINT nFlags, CPoint point);
    void OnLButtonDown (UINT nFlags, CPoint point);
    void OnPaint (HDC hNotUsed);
    void OnMouseMove (UINT nFlags, CPoint point);
    void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
    BOOL OnQueryNewPalette ();
    void OnPaletteChanged (CWindow wndFocus);
    void OnKillFocus (CWindow wndFocus);
    void OnActivateApp (BOOL bActive, DWORD dwThreadID);
    BOOL OnSetCursor (CWindow wnd, UINT nHitTest, UINT message);
};

//-------------------------------------------------------------------------------------------

#define CP_MODE_TEXT 1  // edit text colour
#define CP_MODE_BK   2  // edit background colour (default)

class CColourPicker : public CWindowImpl<CColourPicker, CButton>
{
public:
    DECLARE_WND_SUPERCLASS (NULL, CButton::GetWndClassName ())

    CColourPicker();

    HWND Create (HWND hWndParent, _U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
            DWORD dwStyle = 0, DWORD dwExStyle = 0, _U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL);

    COLORREF GetColour ();
    void SetColour (COLORREF crColour);

    void SetDefaultText (const TCHAR* szDefaultText);
    void SetCustomText (const TCHAR* szCustomText);

    void SetTrackSelection (BOOL bTracking = TRUE)  { m_bTrackSelection = bTracking; }
    BOOL GetTrackSelection ()  { return m_bTrackSelection; }

    void SetSelectionMode (UINT nMode)  { m_nSelectionMode = nMode; }
    UINT GetSelectionMode ()  { return m_nSelectionMode; };

    void SetBkColour (COLORREF crColourBk);
    COLORREF GetBkColour ()  { return m_crColourBk; }
    
    void SetTextColour (COLORREF crColourText);
    COLORREF GetTextColour ()  { return m_crColourText;}

    void SetWindowSize ();
    
public:
    BEGIN_MSG_MAP_EX (CCheckListBox)
        MSG_OCM_DRAWITEM (OnReflectedDrawItem)
        MSG_WM_LBUTTONUP (OnLButtonUp)
        MSG_WM_CREATE (OnCreate)
        MESSAGE_HANDLER (MWM_SELENDOK, OnSelEndOK)
        MESSAGE_HANDLER (MWM_SELENDCANCEL, OnSelEndCancel)
        MESSAGE_HANDLER (MWM_SELCHANGE, OnSelChange)

        DEFAULT_REFLECTION_HANDLER ()
    END_MSG_MAP_EX ()

protected:
    BOOL m_bActive;  // Is the dropdown active?
    BOOL m_bTrackSelection;  // track colour changes?
    COLORREF m_crColourBk;
    COLORREF m_crColourText;
    UINT m_nSelectionMode;
    CRect m_ArrowRect;

public:
    CString m_strDefaultText, m_strCustomText;

protected:
    void OnReflectedDrawItem (int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
    void OnLButtonUp (UINT nFlags, CPoint point);
    int OnCreate (LPCREATESTRUCT lpCreateStruct);
    LRESULT OnSelEndOK (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
    LRESULT OnSelEndCancel (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
    LRESULT OnSelChange (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
};

//-------------------------------------------------------------------------------------------

class IColorEventListener : public IBaseEventListener
{
public:
    virtual void OnColorChanged () = 0;
};

class CVWnd_ColorPicker : public CColourPicker
{
    BEGIN_DECLARE_VOL_NATIVE_WND_CLASS (CVWnd_ColorPicker, IColorEventListener, FALSE)
        MESSAGE_HANDLER (MWM_SELENDOK, OnSelEndOK)
        CHAIN_MSG_MAP (CColourPicker)
    END_DECLARE_VOL_NATIVE_WND_CLASS_MAYBE_CONTAINER ()

public:
    CVWnd_ColorPicker ();

    COLORREF GetCurrentColor () const;
    void SetCurrentColor (COLORREF clrCurrent);
    void SetAllowTransparent (BOOL_P blpAllowTransparent);
    void SetTransparentCaption (const TCHAR* szCaption);

    LRESULT OnSelEndOK (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);

public:
    BOOL_P m_blpAllowTransparent;
    CVolString m_strTransparentCaption;

protected:
    COLORREF m_clrCurrent;
};


#endif
